package com.wf.day_0613.test2;

import lombok.Data;
import com.wf.classRoomTest.A;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author mpk
 * @since 2024/6/12 17:03:35
 */
/*3.使用Object和Conditional类的方法实现：存款 取款线程  参考 课件/图解/3.线程通讯-生产者和消费者模型.png
        共同资源 Account balance=0.0
        存款线程 DepositThread 爸爸, 妈妈
        xx线程正在存款10000元，如果账户有余额则存款失败
        xx线程正在存款10000元，存款后 唤醒 取款线程 取款
        取款线程  WithdrawThread 哥哥,妹妹
        xx线程正在取款10000元，如果账户没有余额则取款失败*/
@Data
public class Account {


    private String name;

    private double balance;

    private Lock lock = new ReentrantLock();

    Condition c1 = lock.newCondition();

    Condition c2 = lock.newCondition();


    Account deposit(double money) {

        lock.lock();
        try {
            if (balance != 0) {
                c1.await();
            }
            if (this.balance != 0 || money < 0) {

                throw new RuntimeException(Thread.currentThread().getName() + "存款失败！！" + "余额为：" + this.balance);

            } else {
                balance = balance + money;
                System.out.println(Thread.currentThread().getName() + "存款成功！" + "余额:" + this.balance);
                c2.signalAll();

            }

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {

            lock.unlock();
        }


        return this;

    }

    Account withdraw(double money) {

        try {
            lock.lock();

            if (balance == 0) {
                c2.await();
            }

            if (money < 0) {
                throw new RuntimeException("取款金额不能为负数！！");
            }
            if (this.balance - money >= 0) {
                this.balance -= money;
                System.out.println(Thread.currentThread().getName() + "取款成功！" + "余额:" + this.balance);
                c1.signalAll();

            } else {

                throw new RuntimeException(Thread.currentThread().getName() + "余额不足！！" + "余额:" + this.balance);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

        return this;


    }


}



